- Tuesday, September 3, 2024
Code "greppability" is when code is easy to search through thanks to easy-to-understand names. Dynamically constructing identifiers (e.g., table names and function names) makes code searching harder. Use flat, unnested structures for namespaces and components as it makes it easier to locate specific elements through simple searches.
- Wednesday, June 12, 2024
Clear, readable code is more valuable than clever code in the long run. This developer's experience at a large tech company revealed that even though clear code might seem trivial, it's actually more difficult to write and maintain. In order to “preserve complexity” for promotion packets, documentation was important for demonstrating the complexity of the work.
- Monday, May 27, 2024
Clever code is difficult to understand. “Clever code” can stem from valuing complex code over readability, premature abstraction, or over-adherence to the DRY (Don't Repeat Yourself) principle. Devs should instead try to write simple code that their future selves can easily understand.
- Thursday, September 5, 2024
Explicit code is better than implicit code because implicit code has a higher number of WTFs per minute (basically being more frustrating and confusing). This post presents two code examples to make this point, showing how explicit code makes it easier to understand and maintain the codebase by clearly defining variables and permissions.
- Wednesday, May 22, 2024
Although clever code feels impressive to write, it's often unmaintainable and unreasonable to write in production. Code that is easy to understand and readable is arguably harder to write than clever code. This article provides tips and resources for getting better at writing clear code, along with an anecdote about the difficulties of writing clear code and an email about coding style from John Carmack.
- Tuesday, June 11, 2024
Great contributions to a codebase prioritize well-tested features over rushed solutions, have TODOs and feature flags to manage ongoing work, and refactor existing code in-place whenever possible. New changes should be broken down into digestible pull requests. They should also have the same patterns and code style of the existing codebase.
- Monday, June 3, 2024
Strong types in programming languages like C++ and Rust, which enforce specific data types and rules for variables, lead to fewer bugs, more expressive APIs, and potentially better performance. They prevent invalid input, improve code clarity, and reduce the need for repetitive error checking (like in JavaScript with undefined).
- Friday, April 26, 2024
Increase has a “no abstractions” principle when designing APIs. This means using real-world naming conventions from underlying networks, modeling resources after immutable real-world events, and separating resources with distinct use cases. The approach may seem more complex at first, but it actually makes the API more predictable, more consistent, and reduces cognitive load for developers.
- Tuesday, August 20, 2024
Good code refactoring is incremental and preserves functionality while avoiding any new unnecessary complexity. Bad refactoring practices include drastic style changes, unnecessary abstractions, inconsistency in code patterns, refactoring without fully understanding the existing code, and ignoring the business context.
- Monday, August 5, 2024
Avoiding barrel files can prevent issues like circular imports and improve development speed by reducing unnecessary module loading. Consistency in file organization can be enforced by lint rules like `import/no-cycle`. A single casing format for filenames is useful for team style guides. While barrel files may be necessary for libraries, they often complicate application code and should be avoided.
- Tuesday, October 1, 2024
The article discusses the concept of "boring code" and its significance in software development, particularly in the context of mobile applications. The author, Jorge Coca, reflects on the qualities that make code effective and easy to work with, emphasizing that good code should be clear, predictable, and devoid of surprises. This perspective emerged from a conversation during a retrospective session where a team member described their codebase as "boring," which the author interpreted as a compliment. Coca argues that much of the functionality in mobile applications is repetitive, involving common tasks such as data fetching, transformation, and presentation. He suggests that producing "boring" code is beneficial because it minimizes unexpected issues, allowing engineering teams to focus on more complex business challenges rather than troubleshooting unforeseen problems. A well-structured codebase that is easy to navigate and well-tested contributes to this sense of predictability. To achieve this "boring" code, the author identifies two key components: creating super declarative and clear APIs, and ensuring that each piece of code is appropriately placed within the project structure. This involves distinguishing between data acquisition components, business rules, and presentation elements. By adhering to these principles, developers can create reusable components that streamline the development process across various applications. Coca concludes by expressing a commitment to sharing knowledge and best practices with the community, indicating plans to release a series of articles focused on transforming code into effective, "boring" code. This approach not only enhances efficiency but also fosters a more enjoyable development experience for teams.
- Thursday, April 18, 2024
Projects benefit from investing upfront in foundational elements like READMEs, developer docs, websites, and clear process documentation. Code quality should always be upheld on the main branch. These kinds of elements are a productivity multiplier when a project gets larger and are much harder to introduce into a large project that doesn't already have them.
- Monday, July 8, 2024
Linus Torvalds emphasizes the importance of data structures over code in software development since good data structures lead to better code design and maintainability. This author supports this view with personal experience, describing how restructuring data in a project allowed the team to move faster in the long run. This prioritization is also how Git grew to be the dominant version control system.
- Monday, June 3, 2024
A three-step process for writing clean code: first, prioritize making the code work, then add testing for correctness, and finally, refactor and clean up the code while relying on the tests.
- Monday, August 19, 2024
Linus Torvalds (the creator of Git and Linux) says that data structures are more important than code in software development since good data structures lead to better code design and maintainability. This article supports this view with personal experience, describing how restructuring data in a project allowed a team to move faster in the long run. This prioritization is also how Git grew to be the dominant version control system.
- Friday, May 31, 2024
The DRY (Don't Repeat Yourself) principle can be harmful if applied prematurely. Early abstractions can lead to unnecessary complexity where future requirements may require independent evolution of seemingly similar looking pieces of code. Instead of blindly following DRY, developers should always think through what code sections are truly redundant or may evolve in the future based on business requirements.
- Thursday, March 7, 2024
The most fundamental goal of software design is to make code understandable. Understandable code is needed for correctness, security, and performance, as a lack of understanding leads to defects, security issues, and misguided performance optimizations. Focusing on understandability means making the code itself readable and providing supporting documentation to clarify complex concepts or system architecture.
- Friday, May 31, 2024
Before applying DRY (Don't Repeat Yourself), consider whether the deduplication is truly redundant or if the functionality will need to evolve independently over time. Applying DRY principles too rigidly leads to premature abstractions that make future changes more complex than necessary. While two sections of code may look the same, they could serve different contexts and business requirements that evolve separately over time. Keep code separate until enough common patterns emerge over time to justify coupling the code together. Tolerate a little duplication in the early stages of development and wait to abstract.
- Friday, September 20, 2024
While every function has the potential to throw an exception, it's more helpful to think about whether the entire function succeeds or fails rather than focusing on individual operations that could cause errors. Make functions more simple to improve readability and reasoning and write clean-up code that keeps a consistent program state regardless of how the function exits.
- Thursday, May 16, 2024
Traditional code reviews, which focus on manually finding errors, have become a bottleneck for engineering teams. With advancements in automated testing and static code analyzers, code reviews can now shift their focus from error-finding to knowledge sharing and long-term codebase health.
- Wednesday, May 22, 2024
Long parameter lists in functions can be hard to understand and maintain. Instead, it's better to create value objects that group related parameters into a single object. This makes the function calls simpler and makes the code more maintainable.
- Wednesday, May 8, 2024
Developers often feel the urge to rewrite code they perceive as messy, even if it's their own relatively recent work. This is because reading code is inherently harder than writing it. However, code that works and has been in production for a long time is often more stable and robust than developers realize.
- Thursday, September 26, 2024
The article discusses the challenges of managing complex conditional logic in programming, particularly in the context of a taxi-hailing mobile app. It highlights a specific example of driver assignment code that suffers from excessive nested if statements, which can lead to confusion and difficulty in maintenance. The author emphasizes the importance of refactoring this code to improve readability and flexibility. To address the issue, the article introduces several techniques for flattening the code structure. The first method involves using guard clauses to eliminate unnecessary nesting. By converting initial checks into guard clauses, the code becomes cleaner and easier to follow. This approach is demonstrated with a revised version of the driver assignment function that reduces the number of nested conditions. Next, the article presents the concept of decision tables, where each conditional check is encapsulated in its own function. This allows for a more organized structure, enabling the logic to be modified simply by changing the entries in the decision table. The use of an array to store these conditions further enhances the clarity of the code. Finally, the article advocates for function composition, suggesting the use of higher-order functions and array methods like `Array.find()` to streamline the driver assignment process. By defining individual functions for each condition, the code not only becomes more modular but also eliminates all nested if statements. The overall outcome of these refactoring techniques is a more maintainable and understandable codebase, which adheres to functional programming principles. The author concludes by noting that these changes not only simplify the logic but also reduce the size of the program, making it more efficient.
- Tuesday, September 10, 2024
Design patterns make certain problems easier to deal with. Some patterns are easier to write in some languages than others. A language update to implement these patterns can make things easier for developers and produce cleaner code. This article presents an example of this where a new feature in Java made a particular design pattern a thing of the past.
- Friday, August 9, 2024
This is a practical guide to refactoring a messy React component through gradual improvements. First, one should make sure that tests are written so that no functional changes occur during refactoring. Then, linting rules should be used to prevent future code duplication and dead code. The guide highlights several key areas for refactoring, including splitting components based on responsibilities and extracting utility functions to improve code organization and maintainability.
- Monday, April 8, 2024
To ship code faster, identify where you spend most of your time: design, coding, testing, review, or deployment. If you’re new to a codebase, focus on understanding code flow, tracing techniques, and learning from experienced colleagues. To optimize testing and review, use feature flags, batch changes, automate testing, and aim for smaller, well-explained code changes for faster reviews.
- Tuesday, April 23, 2024
This author built a large-scale service and found certain principles reappearing throughout the implementation. It's useful to prioritize a single source of truth and minimize mutable state when building something from scratch. Developers should also make sure not to abstract things prematurely and not to overuse mocks when writing tests for their code.
- Wednesday, April 17, 2024
Paper Code is a fast and performant C++ IDE.